import os

from multiprocessing import Queue

import lib, sql

from xdh_logging import initLog
from settings import settings
from nothing import Nothing
from track import Track

log = initLog("subfile")

class SubFile(object):
	"""
	Class that manages a specifc category file that contains all of the tracks in the playlist for that category.
	Designed to use the with statement, and will automatically save a file if the dirty flag is set to true.
	"""

	def __init__(self, cat):
		"""
		Constructs the SubFile instance, loading a category sublist file if it exists.
		"""
		
		self.cat = cat

		self._data = {}

		for row in sql.SubData.getCat(self.cat):
			if (row.sub_category, row.favorite) not in self._data:
				self._data[(row.sub_category, row.favorite)] = set()

			self._data[(row.sub_category, row.favorite)].add(Track(row.track))

			log.debug("({sub}, {favorite}) => {track}".format(sub = row.sub_category, favorite = row.favorite, track = row.track))

		self._original_data = dict(self._data)


	def __enter__(self):
		return self


	def __exit__(self, type, value, traceback):
		
		dels = []
		for key, tracks in self._original_data.iteritems():
			sub, favorite = key[0], key[1]

			for filename in tracks:
				if key not in self._data or filename not in self._data[key]:
					log.debug(u"Removing old: {cat}, {sub}, {fav}, {fname}".format(cat = self.cat, sub = sub, fav = favorite, fname = lib.safe_unicode(lib.fix_filename(filename, reverse = True))))
					dels.append({"category": self.cat, "sub_category": sub, "favorite": favorite, "filename": lib.fix_filename(filename, reverse = True)})

		adds = []
		for key, tracks in self._data.iteritems():
			sub, favorite = key[0], key[1]

			for filename in tracks:
				if key not in self._original_data or filename not in self._original_data[key]:
					log.debug(u"Adding new: {cat}, {sub}, {fav}, {fname}".format(cat = self.cat, sub = sub, fav = favorite, fname = lib.safe_unicode(lib.fix_filename(filename, reverse = True))))
					adds.append({"category": self.cat, "sub_category": sub, "favorite": favorite, "filename": lib.fix_filename(filename, reverse = True)})

		sql.process(sql.SubData, "delete", dels)

		sql.process(sql.SubData, "insert", adds)

		del self._data
		del self._original_data


	def getSub(self, sub, favorite):
		if (sub, favorite) in self.data:
			return self.data[(sub, favorite)]
		else:
			return set()


	@property
	def data(self):
		return self._data


	@property
	def subs(self):
		subs = set()
		for sub, fav in sql.SubData.getSubs(self.cat):
			subs.add((sub, fav))

		return subs


	def setSub(self, sub, favorite, data):
		if len(data) == 0 and (sub, favorite) in self.data:
			del self.data[(sub, favorite)]

		elif len(data) > 0:
			self.data[(sub, favorite)] = data


	def getAll(self):
		return {track for tracks in self.data.itervalues() for track in tracks}


	def getRest(self, my_sub, favorite):
		return {track for key, tracks in self.data.iteritems() for track in tracks if key != (my_sub, favorite)}


	@classmethod
	def getSubFile(cls):
		"""
		Gets the list of existing categories based on what category sublists exist.
		"""
		return {cat for cat in sql.SubData.getCats()}


	@classmethod
	def getPlaylist(cls):
		return {filename for filename in sql.SubData.getPlaylist()}
